package gui;

import static util.Const.*;

import java.awt.*;
import java.awt.event.*;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import treatment.Treatment;
import util.CenterTableCellRenderer;
import util.Util;
import util.comparator.ComparatorByMoney;

import loader.Loader;

@SuppressWarnings("serial")
public class MainFrame extends JFrame implements ActionListener {
	public Loader l;
	private JTable table;
	private DefaultTableModel tableModel;

	public MainFrame() {
		super("LSD-DBMANAGER");
		setLocationByPlatform(true);
		setResizable(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(new GridBagLayout());
	}

	public void actionPerformed(ActionEvent event) {
		if (event.getActionCommand().equals("exportTableToCSV"))
			Util.exportTableToCSV(table);
		else if (event.getActionCommand().equals("About..."))
			about();
		else if (event.getActionCommand().equals("Exit"))
			exit();
		else if (event.getActionCommand().equals("CalculateRatiosByClass"))
			CalculateRatiosByClass();
		else if (event.getActionCommand().equals("CalculateRatiosByCorpo"))
			CalculateRatiosByCorpo();
	}

	private void CalculateRatiosByClass() {
		// Initialisation
		JFrame frame = new JFrame("LSD-BDManager >>> Results by Class");
		frame.setLocationByPlatform(true);
		frame.setResizable(true);
		frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		frame.setLayout(new GridBagLayout());

		DefaultTableModel tableModel = new DefaultTableModel();
		JTable table = new JTable(tableModel);
		TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(
				table.getModel());
		table.setRowSorter(sorter);
		table.setDefaultRenderer(Object.class, new CenterTableCellRenderer());
		TableCellRenderer headerRenderer = table.getTableHeader()
				.getDefaultRenderer();
		((DefaultTableCellRenderer) headerRenderer)
				.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);

		Treatment t = new Treatment(l);
		t.collectDataByClass();
		t.calculateRatiosByClass();

		Object[] newColumnsTitles = {"Class", "CA", "Sum of gross costs",
				"Increased gross cost", "Unit A", "Unitary price A", "Unit B",
				"Unitary price B", "Sum of worked hours", "Price by hour"};

		// fill the data
		Object[][] data = t.RatiosByClasstoPrintableTable();
		tableModel.setDataVector(data, newColumnsTitles);
		sorter.setComparator(2, new ComparatorByMoney());
		sorter.setComparator(3, new ComparatorByMoney());
		sorter.setComparator(5, new ComparatorByMoney());
		sorter.setComparator(7, new ComparatorByMoney());
		sorter.setComparator(9, new ComparatorByMoney());
		table.requestFocusInWindow();

		// Create the table header
		JTableHeader header = table.getTableHeader();
		header.setUpdateTableInRealTime(false);
		header.setFont(new Font("TimesRoman", Font.BOLD, 12));

		// Display the scroll pane
		JScrollPane pane = new JScrollPane(table);

		addComponent(frame.getContentPane(), header, 0, 0, 1, 1, 1.0, 0.0,
				GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
		addComponent(frame.getContentPane(), pane, 0, 1, 1, 3, 1.0, 1.0,
				GridBagConstraints.CENTER, GridBagConstraints.BOTH);

		createMenu(frame);
		frame.pack();
		centerWindows(frame);
		frame.setExtendedState(getExtendedState() | MAXIMIZED_BOTH);
		frame.setVisible(true);
	}
	private void CalculateRatiosByCorpo() {
		// Initialisation
		JFrame frame = new JFrame("LSD-BDManager >>> Results by Corpo");
		frame.setLocationByPlatform(true);
		frame.setResizable(true);
		frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		frame.setLayout(new GridBagLayout());

		DefaultTableModel tableModel = new DefaultTableModel();
		JTable table = new JTable(tableModel);
		TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(
				table.getModel());
		table.setRowSorter(sorter);
		table.setDefaultRenderer(Object.class, new CenterTableCellRenderer());
		TableCellRenderer headerRenderer = table.getTableHeader()
				.getDefaultRenderer();
		((DefaultTableCellRenderer) headerRenderer)
				.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);

		Treatment t = new Treatment(l);
		t.collectDataByCorpo();
		t.calculateRatiosByCorpo();

		Object[] newColumnsTitles = {"Class", "CA", "Sum of gross costs",
				"Increased gross cost", "Unit A", "Unitary price A", "Unit B",
				"Unitary price B", "Sum of worked hours", "Price by hour"};

		// fill the data
		Object[][] data = t.RatiosByCorpotoPrintableTable();
		tableModel.setDataVector(data, newColumnsTitles);
		sorter.setComparator(2, new ComparatorByMoney());
		sorter.setComparator(3, new ComparatorByMoney());
		sorter.setComparator(5, new ComparatorByMoney());
		sorter.setComparator(7, new ComparatorByMoney());
		sorter.setComparator(9, new ComparatorByMoney());
		table.requestFocusInWindow();

		// Create the table header
		JTableHeader header = table.getTableHeader();
		header.setUpdateTableInRealTime(false);
		header.setFont(new Font("TimesRoman", Font.BOLD, 12));

		// Display the scroll pane
		JScrollPane pane = new JScrollPane(table);

		addComponent(frame.getContentPane(), header, 0, 0, 1, 1, 1.0, 0.0,
				GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
		addComponent(frame.getContentPane(), pane, 0, 1, 1, 3, 1.0, 1.0,
				GridBagConstraints.CENTER, GridBagConstraints.BOTH);

		createMenu(frame);
		frame.pack();
		centerWindows(frame);
		frame.setExtendedState(getExtendedState() | MAXIMIZED_BOTH);
		frame.setVisible(true);
	}

	private void about() {
		JOptionPane.showMessageDialog(this, "lsd-dbmanager", "About",
				JOptionPane.PLAIN_MESSAGE);

	}

	private void exit() {
		System.exit(0);
	}

	static void setTable(JTable table) {

		table.setBorder(new LineBorder(Color.black));
		table.setAutoscrolls(true);
		table.setGridColor(Color.black);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table.setAutoCreateRowSorter(true);
		table.setDefaultRenderer(Object.class, new CenterTableCellRenderer());
		TableCellRenderer headerRenderer = table.getTableHeader()
				.getDefaultRenderer();
		((DefaultTableCellRenderer) headerRenderer)
				.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);

		table.getColumn("Rss").setPreferredWidth(20);
		table.getColumn("Corpo").setPreferredWidth(70);
		table.getColumn("Corpo name").setPreferredWidth(420);
		table.getColumn("Zip code").setPreferredWidth(60);
		table.getColumn("Municipal code").setPreferredWidth(100);
		table.getColumn("Clsc").setPreferredWidth(45);
		table.getColumn("Existing since").setPreferredWidth(90);
		table.getColumn("Class").setPreferredWidth(50);
		table.getColumn("Group").setPreferredWidth(50);
		table.getColumn("CA").setPreferredWidth(35);
		table.getColumn("Univers").setPreferredWidth(60);
		table.getColumn("SSDom").setPreferredWidth(50);
		table.getColumn("# of worked hours").setPreferredWidth(120);
		table.getColumn("Gross cost").setPreferredWidth(75);
		table.getColumn("Unit A").setPreferredWidth(85);
		table.getColumn("Unit B").setPreferredWidth(85);
	}

	private static void addComponent(Container container, Component component,
			int gridx, int gridy, int gridwidth, int gridheight,
			double weightx, double weighty, int anchor, int fill) {
		GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
				gridwidth, gridheight, weightx, weighty, anchor, fill,
				new Insets(10, 10, 10, 10), 0, 0);
		container.add(component, gbc);
	}

	private void centerWindows(JFrame frame) {
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		// Determine the new location of the window
		int w = frame.getSize().width;
		int h = frame.getSize().height;
		int x = (dim.width - w) / 2;
		int y = (dim.height - h) / 2;
		// Move the window
		frame.setLocation(x, y);
	}

	private void createMenu(JFrame frame) {
		JMenu menu1 = new JMenu("File");

		JMenuItem menuItem = new JMenuItem("Open");
		menu1.add(menuItem);
		menuItem.addActionListener(this);

		menuItem = new JMenuItem("Export table to CSV");
		menuItem.setActionCommand("exportTableToCSV");
		menuItem.addActionListener(this);
		menu1.add(menuItem);

		menuItem = new JMenuItem("Exit");
		menuItem.addActionListener(this);
		menu1.add(menuItem);

		JMenu menu2 = new JMenu("Help");

		menuItem = new JMenuItem("About...");
		menuItem.addActionListener(this);
		menu2.add(menuItem);

		JMenuBar bar = new JMenuBar();
		bar.add(menu1);
		bar.add(menu2);

		frame.setJMenuBar(bar);
	}

	public void load() {
		// Display a "please wait" message
		JLabel label = new JLabel("Please wait while loading data...");
		label.setFont(new Font("Arial", Font.BOLD, 16));
		label.setPreferredSize(new Dimension(380, 85));
		label.setHorizontalAlignment(SwingConstants.CENTER);
		label.setVerticalAlignment(SwingConstants.CENTER);
		getContentPane().add(label);
		pack();
		centerWindows(this);
		setVisible(true);

		// Open files
		try {
			FileReader ETAB0X = new FileReader(DATA_PATH + "ETAB" + YEAR
					+ ".TXT");
			FileReader ETABCLSC = new FileReader(DATA_PATH + "ETABCLSC.TXT");
			FileReader DONFIN0X = new FileReader(DATA_PATH + "DONFIN" + YEAR
					+ ".TXT");
			FileReader DONADD0X = new FileReader(DATA_PATH + "DONADD" + YEAR
					+ ".TXT");
			FileReader UNIT0X = new FileReader(DATA_PATH + "UNIT" + "06"
					+ ".TXT");
			// FileReader LABO0X = new FileReader(DATA_PATH + "LABO" + YEAR
			// + ".TXT");
			FileReader TYPECA = new FileReader(DATA_PATH + "TYPECA.TXT");

			// Load Data
			l = new Loader(DONFIN0X, ETAB0X, ETABCLSC, DONADD0X, UNIT0X,
					TYPECA, ANNEE);
			try {
				DONFIN0X.close();
				ETAB0X.close();
				ETABCLSC.close();
				DONADD0X.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

			// Create the data table
			Object[][] data = l.toPrintableTable(l.getDb());
			String[] columnsTitles = {"Rss", "Corpo", "Corpo name", "Zip code",
					"Municipal code", "Clsc", "Existing since", "Class",
					"Group", "CA", "Univers", "SSDom", "# of worked hours",
					"Gross cost", "Unit A", "Unit B"};

			// Disable the please wait message
			remove(label);
			setVisible(false);

			createMenu(this);

			Container container = getContentPane();

			tableModel = new DefaultTableModel(data, columnsTitles);
			table = new JTable(tableModel);
			setTable(table);

			// Create the table header
			JTableHeader header = table.getTableHeader();
			header.setUpdateTableInRealTime(false);
			header.setFont(new Font("TimesRoman", Font.BOLD, 12));

			// Display the scroll pane
			JScrollPane pane = new JScrollPane(table);

			addComponent(container, header, 0, 0, 1, 1, 1.0, 0.0,
					GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
			addComponent(container, pane, 0, 1, 1, 3, 1.0, 1.0,
					GridBagConstraints.CENTER, GridBagConstraints.BOTH);

			JButton b1 = new JButton("Calculate Ratios by Class");
			b1.setActionCommand("CalculateRatiosByClass");
			JButton b2 = new JButton("Calculate Ratios by Corpo");
			b2.setActionCommand("CalculateRatiosByCorpo");

			addComponent(container, new JPanel(), 1, 1, 1, 1, 0.0, 1.0,
					GridBagConstraints.CENTER, GridBagConstraints.VERTICAL);
			addComponent(container, b1, 1, 2, 1, 1, 0.0, 0.0,
					GridBagConstraints.SOUTH, GridBagConstraints.NONE);
			addComponent(container, b2, 1, 3, 1, 1, 0.0, 0.0,
					GridBagConstraints.SOUTH, GridBagConstraints.NONE);

			// Listen for actions on buttons 1 and 3.
			b1.addActionListener(this);
			b2.addActionListener(this);
			// getRootPane()
			// .setWindowDecorationStyle(JRootPane.INFORMATION_DIALOG);

			pack();
			centerWindows(this);
			setExtendedState(getExtendedState() | MAXIMIZED_BOTH);
			setVisible(true);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

	}
}